import gevent
from gevent import monkey
monkey.patch_all()

import argparse
import socket

from app import app
from settings import STATIC_PATH
from utils.log import logger


class WebServer:

    def __init__(self, host='', port=80):
        # 创建TCP服务端socket
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口号复用
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定ip和端口号
        self.server.bind((host, port))
        # 设置监听
        self.server.listen(128)

    @staticmethod
    def handle_client_request(client, address: tuple):
        """处理客户端 http 请求

        :param client: 与客户端通信的套接字
        :param address: 客户端的连接地址(ip, port)
        :return:
        """
        recv: bytes = client.recv(4096)
        if not recv:
            logger.info('客户端【%s:%s】已下线, 正在断开连接...' % address)
            client.close()
            return

        request = recv.decode()
        client.send(app.application(STATIC_PATH, request))
        client.close()

    def start(self):
        """启动Web服务器

        :return:
        """
        logger.info("Web服务器已经启动, 等待客户端连接中...")
        while True:
            client, address = self.server.accept()
            logger.info("客户端【%s:%s】已上线, 正在连接中..." % address)

            # 协程版
            gevent.spawn(self.handle_client_request, client, address)

            # 线程版
            # t = threading.Thread(target=self.handle_client_request,
            #                      args=(client, address),
            #                      daemon=True)
            # t.start()

            # 进程版
            # p = multiprocessing.Process(target=self.handle_client_request,
            #                             args=(client, address),
            #                             daemon=True)
            # p.start()
            # client.close()


def main():
    # 获取命令行启动参数
    parser = argparse.ArgumentParser()
    parser.add_argument('--host', type=str,
                        default='', action='store',
                        nargs='?', metavar='hostname',
                        help='Specify alternative hostname '
                             '[default: ""]')
    parser.add_argument('-p', '--port', type=int,
                        default=80, action='store',
                        nargs='?', metavar='hostport',
                        help='Specify alternate port [default: 80]')

    args = parser.parse_args()
    # 创建web服务器并启动
    WebServer(args.host, args.port).start()


if __name__ == '__main__':
    main()
